home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / clang / bueh16.zip / BUEH.C next >
C/C++ Source or Header  |  1994-08-26  |  4KB  |  156 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*  BUEH.C - Example of the Borland Unresolved Entry Hook function.         */
  4. /*                                                                          */
  5. /*  The theory involved is as follows:  If the loader finds a call to a     */
  6. /*  function in User or Kernel that RTM doesn't implement, it looks for     */
  7. /*  a function in your .EXE called BORLANDUNRESOLVEDENTRYHOOK.  If this     */
  8. /*  function (known as BUEH) is found, the module and ordinal or function   */
  9. /*  name is passed.  The BUEH is required to return the address of a        */
  10. /*  function that will then be used for this entry.  In other words, if     */
  11. /*  the real function doesn't exist, you get a chance to redirect it to     */
  12. /*  some other function that can simulate the functionality.                */
  13. /*                                                                          */
  14. /*  Warning: If this file is not used as a seperate module that is linked   */
  15. /*           as the first segment, then the data segment CANNOT be used.    */
  16. /*           This example does not assume that the data segment will be     */
  17. /*           availible.  Therefore be careful when extending this code to   */
  18. /*           handle additional unresolved functions.  Don't assume that     */
  19. /*           literal strings can be used from the main entry hook proc.     */
  20. /*                                                                          */
  21. /****************************************************************************/
  22.  
  23. #include <windows.h>
  24. #include <stdio.h>
  25. #include <dos.h>
  26. #include <process.h>
  27.  
  28. // These two signatures are simply the first 4 chars in the module names.
  29. // This is used so that we don't have to rely on the data segment being
  30. // fixed up at this point.
  31. #define KERNEL_SIG 0x4E52454BL
  32. #define USER_SIG   0x52455355L
  33.  
  34. #ifdef __DPMI16__
  35.  
  36. void PrintStr (char *s, int mode)
  37. {
  38.   char *p = s;
  39.   char c;
  40.   while (*p)
  41.   {
  42.     c = *p;
  43.     _DL = c;
  44.     _AH = 0x02;
  45.     geninterrupt (0x21);
  46.     p++;
  47.   }
  48.  
  49.   if (mode == 1)
  50.   {
  51.     _DL = 10;
  52.     _AH = 0x02;
  53.     geninterrupt (0x21);
  54.  
  55.     _DL = 13;
  56.     _AH = 0x02;
  57.     geninterrupt (0x21);
  58.   }
  59.   else
  60.   if (mode == 2)
  61.   {
  62.     _DL = 0x20;
  63.     _AH = 0x02;
  64.     geninterrupt (0x21);
  65.   }
  66. }
  67.  
  68. char ToHexAscii (char c)
  69. {
  70.   if (c < 0x0A)
  71.     return c | 0x30;
  72.  
  73.   return 'A'+ (c - 0x0A);
  74. }
  75.  
  76. void PrintByte (unsigned char num, int mode)
  77. {
  78.   char str[3];
  79.   char un = num >> 4;
  80.   char ln = num & 0x0F;
  81.  
  82.   str[0] = ToHexAscii (un);
  83.   str[1] = ToHexAscii (ln);
  84.   str[2] = 0;
  85.  
  86.   PrintStr (str, mode);
  87. }
  88.  
  89. void PrintNum (unsigned short num, int mode)
  90. {
  91.   PrintByte ((num>>8), 0);
  92.   PrintByte ((num & 0x00FF), mode);
  93. }
  94.  
  95. void __pascal __export BUEH_BigError (void)
  96. {
  97.   printf ("\nNon fixed-up function called.\n");
  98.   exit (-1);
  99. }
  100.  
  101. WORD __pascal _export BUEH_USER_GetFocus (void)
  102. {
  103.   printf ("\nUSER.GetFocus called.\n");
  104.   return 0;
  105. }
  106.  
  107. void __pascal _export BUEH_KERNEL_Yield (void)
  108. {
  109.   printf ("\nKERNEL.Yield called.\n");
  110. }
  111.  
  112. #pragma argsused
  113. void * __pascal _export BorlandUnresolvedEntryHook (char *modname, int isOrd, char *Entry)
  114. {
  115.   unsigned long far *lp = (unsigned long far *)modname;
  116.   int ord = 0;
  117.   if (isOrd)
  118.     ord = FP_OFF (Entry);
  119.  
  120.   if (isOrd)
  121.   {
  122.     if (*lp == KERNEL_SIG)
  123.     {
  124.       switch (FP_OFF (Entry))
  125.       {
  126.         case 29:  return BUEH_KERNEL_Yield;
  127.       }
  128.     }
  129.     else
  130.     if (*lp == USER_SIG)
  131.     {
  132.       switch (FP_OFF (Entry))
  133.       {
  134.         case 23:  return BUEH_USER_GetFocus;
  135.       }
  136.     }
  137.   }
  138.  
  139.   // If the function wasn't handled, then print out it's module and
  140.   // ordinal (in hex) for the user to see.
  141.  
  142.   PrintStr (modname, 2);
  143.   if (isOrd)
  144.     PrintNum (ord, 1);
  145.   else
  146.     PrintStr (Entry, 1);
  147.  
  148.   // and return the address of a function that will terminate the app. before
  149.   // it has a chance to cause a GP fault.
  150.  
  151.   return BUEH_BigError;
  152. }
  153.  
  154. #endif  // __DPMI16__
  155.  
  156.